﻿/*
 * (c) Stefan Bojarovski 2010
 * */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASTBuilder
{
    class LetNode : NodesCollection, ITreeNode
    {
        private LexemeType lexType = LexemeType.LET_OPERATOR;
        private ITreeNode Name; //Identifier
        private ITreeNode Substituent;  //Expression
        private ITreeNode targetExpression; //Expression

        public LetNode(ITreeNode someId, ITreeNode subsExpr, ITreeNode targetExpr)
        {
            Name = someId;
            Substituent = subsExpr;
            targetExpression = targetExpr;
        }
        public LexemeType getLexemeType()
        {
            return lexType;
        }
        public void printNode(String parentLevel, StreamWriter someStream)
        {
            someStream.WriteLine(parentLevel + " " + "Let Binding: ");
            Name.printNode(parentLevel + " ", someStream);
            someStream.WriteLine(parentLevel + " " + "Equals: ");
            Substituent.printNode(parentLevel + " ", someStream);
            someStream.WriteLine(parentLevel + " " + "In: ");
            targetExpression.printNode(parentLevel + " ", someStream);
        }
        public List<Command> evalNode(ref Direction next,
                                        ref Dictionary<String, Pair<IdentifierType, object>> Environment)
        {
            List<Command> result = new List<Command>();
            if (next != Direction.JUMP)
            {
                IdentifierNode idNode = (IdentifierNode)Name;
                String id = idNode.getName();


                if (!Environment.ContainsKey(id))
                {
                    Environment.Add(id, new Pair<IdentifierType, object>(IdentifierType.EXPRESSION, Substituent));
                    result.Add(new Command(CommandType.ENVIRONMENTMODIFICATION, id, Substituent));
                }
                else
                {
                    if (Environment[id].getLeft() != IdentifierType.EXPRESSION)
                    {
                        result.Add(new Command(CommandType.ERRORUNCOMPATIBLETYPES, id, null));
                    }
                    else
                    {
                        Environment[id].setRight(Substituent);
                        result.Add(new Command(CommandType.ENVIRONMENTMODIFICATION, id, Substituent));
                    }
                }
                result.Concat((IEnumerable<Command>)targetExpression.evalNode(ref next, ref Environment)[0]);
                return result;
            }
            else
            {
                result.Add(new Command(CommandType.VOID, null, null));
                return result;
            }
        }
    }
}
